package com.bootdo.api.upload;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.bootdo.api.WalletRequest;
import com.bootdo.api.domain.OfflineBody;
import com.bootdo.api.domain.OfflineHead;
import com.bootdo.api.domain.OfflineTradSpec;
import com.bootdo.api.textUtil.Encipherment;
import com.bootdo.api.textUtil.FileUtil;
import com.bootdo.api.textUtil.Tools;
import com.bootdo.api.util.ftp.Ftp;
import com.bootdo.api.util.ftp.FtpUtil;

import net.sf.json.JSONObject;

/**
 * 实名认证材料的提交 和审核文件的下载解析
 * 
 * @author:lzr
 * @time:2017年8月3日 下午10:41:33
 */
@Component
public class RealNameTask {
	private static final Logger log = LoggerFactory.getLogger(RealNameTask.class);
	byte[] raw = { (byte) 0xA5, 0x45, 0x64, 0x17, 0x42, 0x00, 0x35, 0x15, 0x15, 0x24, 0x67, 0x18, 0x06, (byte) 0x84,
			0x15, (byte) 0x9A };
	// 钱包接口地址
	private static String walletUrl = "http://218.85.66.151:60037/Purse/Transaction";//测试环境地址:http://218.6.64.250:60059/Purse/Transaction
	// 钱包密钥
	private static String key = "A545641742003515152467180684159A";
	// ftp地址、端口、账户、密码
	private static String ipAddr = "218.85.66.151";// "47.91.136.143"
	private static Integer port = 60034;// 21
	private static String userName = "zzbike";// "shengka"
	private static String pwd = "Fjsykt2015";// "123456"
	/*
	 * //ftp地址、端口、账户、密码(测试) private static String ipAddr = "47.91.136.143";
	 * private static Integer port = 21;//21 private static String userName =
	 * "shengka"; private static String pwd = "123456";
	 */
	private static Ftp ftp;
	private static String CorpID = "115239904413001";

	// ========================审核文件提交 begin==================================
	// 审核文件提交
	public int upload(OfflineBody body, OfflineHead head, String Amount, String OrderId, String Resource) {
		try {
			log.info("===================RealNameTask  begin==================");
			int id = 100;
			String trCode = "5021";
			String date = Tools.getDate2();
			String messageId = String.format("%s%012d", new Object[] { trCode, Integer.valueOf(id + 1) });
			String trDate = Tools.formatDate(date, "yyyyMMdd", "yyyyMMdd");
			SimpleDateFormat format = new SimpleDateFormat("HHmmss");
			Date time = new Date();
			int random = (int) ((Math.random() * 9 + 1) * 100000);

			DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
			Calendar calendar = Calendar.getInstance();
			String dateName = df.format(calendar.getTime());
			int amount = (int) Math.round(Double.parseDouble(Amount)*100);//计算交易金额（分）
			/*// 请求钱包接口所需参数
			JSONObject json = new JSONObject();
			json.put("phoneNumber", "18760371097");//18600927320
			json.put("orderId",body.getTermSeq());
			json.put("transTime", OrderId);
			json.put("amount", amount);
			json.put("transType", 1);
			json.put("extra", "{\"terminalId\":\""+zero(body.getSamID(),12)+"\",\"terminalTransNum\":"+Integer.parseInt(body.getSamSeq())+"}");//
			log.info("给钱包方的数据:" + json.toString());
			// 加密类对象
			String aesMsg = Encipherment.Encrypt(json.toString(), raw);
			String md5Msg = Encipherment.encrypt32(aesMsg);
			String sendMsg = aesMsg + md5Msg;
			log.info("发送的加密报文：" + sendMsg);

			// 发送钱包POST请求类
			String request = WalletRequest.jsonPost(walletUrl, sendMsg);
			log.info("钱包响应的报文：" + request);

			// 解密响应报文
			String response = Encipherment.Decrypt(request, raw);*/
			
			
			// 将JSON字符串转换成JSON对象
			// 解密响应报文
			String response = Encipherment.Decrypt(Resource, raw);
			log.info("自行车提供的钱包响应密文解密：" + response);
			JSONObject object = JSONObject.fromObject(response);
			log.info("钱包response:" + object.toString());
			JSONObject msg = JSONObject.fromObject(object.get("msg"));
			String purse = msg.get("purse").toString();
			
			char[] rtn = "\r\n".toCharArray();
	        StringBuffer strBuffer = new StringBuffer();
	        for (int i=0;i< rtn.length;i++){
	            strBuffer.append(Integer.toHexString(rtn[i]).toUpperCase());
	        }
			OfflineTradSpec special = new OfflineTradSpec();
			String txnAmt = "0";
			String Balance = "0";
			if(msg.has("txnAmt")){
			txnAmt = msg.getString("txnAmt");//计算交易金额（分）
			Balance = new BigDecimal(msg.getString("balance")).multiply(new BigDecimal("100")).toString();//计算消费前卡余额（分）
			}
			if (purse.equals("commonPurse")) {
				//body.setIssuerID(supplement(msg.getString("purse"), 16)); // 发卡机构标识
				body.setIssuerID("01523990FFFFFFFF"); // 发卡机构标识
				body.setCardID(supplement(msg.getString("cardId"), 20)); // 卡内号
				body.setCardDebitCnt(frontZero(msg.getString("cardDebitCnt"), 6));// 卡计数器
				body.setCardEndDate(msg.getString("cardEndDate").replace("|", "0")); // 卡结束日期
				body.setBalance(frontZero(Balance, 12)); // 消费前卡余额（分）10进制
				body.setTAC(supplement(msg.getString("tac"), 16)); // 交易认证码
				body.setCardRand(frontZero(msg.getString("cardRand"), 8)); // 不可预知数
				body.setKeyVer(msg.getString("keyVer")); // 密钥版本
				body.setComputTag(msg.getString("computTag")); // 算法标识
				body.setKeyIndex(msg.getString("keyIndex")); // 密钥索引号
				body.setTransType("0" + msg.getString("transactionType")); // 交易标识
				body.setExtendType(frontZero(msg.getString("extendType"),2)); // 行业特色应用类型
				body.setTxnAmt(frontZero(txnAmt,12)); // 交易金额（分）
				body.setChargetype("00"); // 收费类型

				body.setOrigAmt(frontZero(txnAmt,12));// 应收金额
				body.setBusinessIndex("04"); // 行业索引
			} else if(purse.equals("gwyPurse")){

				body.setIssuerID("01523990FFFFFFFF"); // 发卡机构标识
				body.setCardID(supplement(msg.getString("cardId"), 20)); // 卡内号
				body.setCardDebitCnt(frontZero(msg.getString("cardDebitCnt"), 6));// 卡计数器
				body.setCardEndDate(msg.getString("cardEndDate").replace("|", "0")); // 卡结束日期
				body.setBalance(frontZero(Balance, 12)); // 消费前卡余额（分）10进制
				body.setTxnAmt(frontZero(txnAmt,12)); // 交易金额（分）
				body.setTAC(supplement(msg.getString("tac"), 16)); // 交易认证码
				body.setCardRand(frontZero(msg.getString("cardRand"), 8)); // 不可预知数
				body.setKeyVer(msg.getString("keyVer")); // 密钥版本
				body.setComputTag(msg.getString("computTag")); // 算法标识
				body.setKeyIndex(msg.getString("keyIndex")); // 密钥索引号
				body.setTransType("0" + msg.getString("transactionType")); // 交易标识
				body.setChargetype("02"); // 收费类型
				body.setExtendType(frontZero(msg.getString("extendType"),2)); // 行业特色应用类型
				body.setOrigAmt(frontZero(txnAmt,12));// 应收金额
				body.setBusinessIndex("01"); // 行业索引(暂时写死)
			} else if(purse.equals("localPurse")){
				return 2;
			}
			body.setPosID(zero(body.getSamID(),12));// PSAM设备号
			body.setSamID(supplement(zero(body.getSamID(),12),16));//PSAM卡号
			body.setTermSeq(frontZero(body.getSamSeq(),12));//终端流水号
			body.setTermID(supplement(zero(body.getTermID(),12),18));//终端编号
			head.setRecNum("00000");// 记录总数
			head.setRecAmt(frontZero(txnAmt,12));
			//head.setRecAmt(frontZero(msg.getString("txnAmt"), 12));// 金额总数
			body.setCardType("01"); // 主卡类型    			 钱包未提供、暂时默认01
			head.setCorpID(CorpID);
			head.setReclens(frontZero("1", 4)); // 单笔交易长度
			head.setIsTSUsed("1"); // 特有数据启用标志
			head.setReserved("FFFFFFFFFFFFFFFFFFFF");// 保留域
			head.setRtnSign1("\r\n"); // 换行
			body.setTransID(frontZero("1", 5)); // 交易序号
			body.setPosOprID(supplement(trDate, 20));// 操作员编号
			body.setCardCsn(zero("0", 8));// 卡CSN(可以忽略)
			body.setCardModel("01"); // 卡交易模式
			body.setTxnDate(OrderId.substring(0, 8)); // 交易发生日期
			body.setTxnTime(OrderId.substring(8, 14));// 交易发生时间

			head.setVersion("02"); // 文件版本
			body.setTxnType("362"); // 交易类型
			head.setRtnSign("\r\n");// 换行
			body.setECCIssAppData(frontZero("0", 64));// 发卡行应用数据？？？
			body.setTxnAmtCode("156"); // 交易货币代码
			body.setOtherAmt(zero("0", 12)); // 其它金额
			body.setCoutryCode("156");// 终端国家代码
			body.setTermChk(frontZero("0", 10)); // 终端验证结果
			body.setECCTranTp(zero("0", 2)); // 电子现金交易类型
			body.setECCAIP(zero("0", 4)); // 应用交互特征
			body.setCardVerNo(frontZero("1", 2)); // 卡内版本号
			body.setPanSeq(frontZero("1", 2)); // Pan序号
			body.setRsvd("FFFFFFFFFFFFFFFFFF"); // 保留域
			body.setTestFlag("0"); // 测试标记
			special.setDtlRecNum("0001");		 //细目记录数固定0001
			special.setDtlRecType("1041");		 //细目记录类型
			special.setInID("000000000000");	 //借车站点
			special.setInTime("00000000000000"); //借车时间YYYYMMDDHH24MMSS
			special.setOutID("000000000000");	 //还车站点
			special.setOutTime("00000000000000");//还车时间YYYYMMDDHH24MMSS

			body.setTradSpec(special); // 特有数据
			body.setRtnSign2("\r\n"); // 回车符
			body.setNullLine("");

			// 本地路径
			String local = getPath() + "/upload/xml/";
			String local1 = getPath() + "/upload/transfer/";

			String index = getFileNum(local, CorpID + trDate);
			
			String newfileName = "FH" + "A0" + CorpID + trDate + index;
			String oldfileName = "testold" + trDate;
			log.info(String.format("fileName:%s", newfileName));

			// 文件全路径
			String fileUrl = local + newfileName;
			String oldfileUrl = local1 + oldfileName;
			countNumber(oldfileUrl,body,head);
			FileUtil.writeFile(local1, oldfileName, head, body, "GBK");
			delFile(local1, oldfileName);
			countMoney(fileUrl,body,head);
			int dataCount = count(fileUrl, oldfileUrl, head);

			// 文件上传FTP
			//boolean fileResult = uploadFileToFtp(fileUrl, newfileName);
			log.info("数据存储成功");
		} catch (Exception e) {
			log.info("================提交审核文件失败======================");
			return 1;
		}
		return 0;
	}
	
	//定时上传
	@Scheduled(cron="0 0 2 * * ?")
	public void cron() throws Exception{
		Calendar ca = Calendar.getInstance();
		ca.setTime(new Date());
		ca.add(Calendar.DATE, -1);
		String  yestedayDate = new SimpleDateFormat("yyyyMMdd").format(ca.getTime());
		String newfileName = "FH" + "A0" + CorpID + yestedayDate;
		
		String local = getPath() + "/upload/xml/";
		String fileName = judgeFile(local,newfileName);
		if(fileName != null){
			boolean fileResult = uploadFileToFtp(local+fileName, fileName);
			if(fileResult){
				log.info(yestedayDate+"日文件上传成功(当前时间"+new SimpleDateFormat("yyyy/MM/dd HH:mm").format(new Date())+")");
			}else{
				log.info(yestedayDate+"日文件上传失败(当前时间"+new SimpleDateFormat("yyyy/MM/dd HH:mm").format(new Date())+")");
			}
		}else{
			log.info("系统无"+yestedayDate+"日数据文件.");
		}
		
	}
	
	//判断前一天文件是否存在
	private static String judgeFile(String local, String newfileName){
		File file = new File(local);
		File[] fs = file.listFiles();
		if(file.exists()){
			for(File f : fs){
				if(f.isFile()){
					if(newfileName.equals(f.getName().substring(0, 27))){
						return f.getName();
					}
				}
			}
		}
		return null;
	}
	/**
	 * 将文件上传至FTP服务器文件夹内
	 * 
	 * @return
	 * @throws Exception
	 */
	private static boolean uploadFileToFtp(String fileUrl, String fileName) {
		// 文件上传路径
		String fileUploadUrl = "/tmp";

		boolean uploadFlag = false;
		try {
			boolean connectFlag = FtpUtil.connectFtp(getFtp(fileUploadUrl));
			if (connectFlag) {
				File file = new File(fileUrl);
				// 文件上传
				uploadFlag = FtpUtil.upload(file);
				if (!uploadFlag) {
					throw new Exception("上传文件失败");
				} else {
					FTPClient ftp = FtpUtil.connectFtp1(getFtp(fileUploadUrl));
					ftp.rename("/tmp/" + fileName, "/upload/" + fileName);
				}
			}
		} catch (Exception e) {
			log.info("===========上传文件失败======" + new Date() + "==============");
			log.info(e.toString());
			uploadFlag = false;
		} finally {
			FtpUtil.closeFtp();
		}
		return uploadFlag;
	}

	/**
	 * 获得ftp对象
	 * 
	 * @return
	 * @throws Exception
	 */
	private static Ftp getFtp(String path) throws Exception {
		if (ftp == null || StringUtils.isNotBlank(path)) {
			ftp = new Ftp(ipAddr, port, userName, pwd, path);
		}
		return ftp;
	}

	// 获得项目的路径
	private static String getPath() {
		String path = RealNameTask.class.getClassLoader().getResource("").getPath();
		// 截取项目路径
		int end = path.length() - "WEB-INF/classes/".length();
		path = path.substring(0, end);
		return path;
	}

	// 长度不够补充空格
	public static String supplement(String data, int length) {
		int leng = length - data.length();
		if (leng > 0) {
			for (int i = 0; i < leng; i++) {
				data += " ";
			}
		}
		return data;
	}

	// 后面填充0
	public static String zero(String data, int length) {
		int leng = length - data.length();
		if (leng > 0) {
			for (int i = 0; i < leng; i++) {
				data += "0";
			}
		}
		return data;
	}

	// 前面填充0
	public static String frontZero(String data, int length) {
		int leng = length - data.length();
		if (leng > 0) {
			for (int i = 0; i < leng; i++) {
				data = "0" + data;
			}
		}
		return data;
	}

	public static void delFile(String local1, String oldfileName) {
		File file = new File(local1);
		File[] f = file.listFiles();
		File oldfile = new File(local1 + oldfileName);
		if (file.exists()) {
			for (File fs : f) {
				if (fs.getName().equals(oldfileName)) {
				} else {
					File discard = new File(local1 + fs.getName());
					discard.delete();
				}
			}
		}
	}

	// 判断文件是否已存在
	public static String getFileNum(String path, String fileName) {
		File file = new File(path);
		File[] f = file.listFiles();
		if (file.exists()) {
			for (File fs : f) {
				if (fs.isFile()) {
					if (fileName.equals(fs.getName().substring(4, 27)))
						return fs.getName().substring(27);
				} else {
					getFileNum(fs.getAbsolutePath(), fileName);
				}
			}
			// 计算文件个数
			int i = f.length;
			String count = String.valueOf(i + 1);
			String index = frontZero(count, 6);
			return index;
		}
		return "000001";
	}

	public static int count(String fileUrl, String oldfileUrl, OfflineHead head) {
		File file = new File(oldfileUrl);
		File newfile = new File(fileUrl);
		File[] f = file.listFiles();
		if (file.exists()) {
			try {
				BufferedReader br = new BufferedReader(new FileReader(oldfileUrl));
				FileWriter fw = new FileWriter(newfile);
				String line = "";
				int lineCount = 1;
				int length = 0;
				while ((line = br.readLine()) != null) {
					if(lineCount > 2){
						length =line.length();
					}
					lineCount++;
				}
				int count = lineCount;
				lineCount = 1;
				String sCount = String.valueOf(count - 3);
				head.setRecNum(frontZero(sCount, 5));// 记录总数
				head.setReclens(frontZero(String.valueOf(length+2),4));
				BufferedReader br1 = new BufferedReader(new FileReader(oldfileUrl));
				while ((line = br1.readLine()) != null) {
					String retract = "\r\n";
					if (lineCount == 1) {
						retract = "";
						line = "";
					}

					if (lineCount == 2) {
						retract = "";
						head.setRtnSign1("");
						line = head.toString();
					}
					fw.write(retract);
					fw.write(line);
					fw.flush();
					lineCount++;
				}
				fw.write("\r\n");
				br.close();
				br1.close();
				fw.close();
				return lineCount;
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return 3;
	}

	public static String countNumber(String fileUrl,OfflineBody body,OfflineHead head){
		File file = new File(fileUrl);
		File[] f = file.listFiles();
		String sCount = "";
		if (file.exists()) {
				try {
					BufferedReader br = new BufferedReader(new FileReader(fileUrl));
					String line = "";
					int lineCount = 1;
					while ((line = br.readLine()) != null) {
						lineCount++;
					}
					int count = lineCount;
					sCount = String.valueOf(count-2);
					body.setTransID(frontZero(sCount, 5)); // 交易序号
					br.close();
					
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		return sCount;
		}
		return sCount;
	}
	public static String countMoney(String fileUrl,OfflineBody body,OfflineHead head){
		File file = new File(fileUrl);
		File[] f = file.listFiles();
		String sCount = "";
		if (file.exists()) {
				try {
					BufferedReader br = new BufferedReader(new FileReader(fileUrl));
					String line = "";
					int lineCount = 1;
					int money = 0;
					while ((line = br.readLine()) != null) {
						if(lineCount == 2){
							String all = line.substring(20, 32);
							money = Integer.parseInt(all);
						}
						lineCount++;
					}
					int one = Integer.parseInt(body.getOrigAmt());
					head.setRecAmt(frontZero(String.valueOf(one+money),12));
					br.close();
					
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		return sCount;
		}
		return sCount;
	}
}
